package com.apop.common.log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;

/**
 * 日志拦截
 * @ClassName LogInterceptor
 * @author Jiayi Zheng
 * @date 2021/11/10 15:35
 * @Description:
 * @version V1.0
 */
@Component
@Slf4j
public class LogInterceptor extends HandlerInterceptorAdapter {

    /**
     * 预处理回调方法，实现处理器的预处理
     * 返回值：true表示继续流程；false表示流程中断，不会继续调用其他的拦截器或处理器
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute("REQUEST_START_TIME", new Date());

        //获取请求参数信息
        String paramData = JSON.toJSONString(request.getParameterMap(), SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);

        //获取请求客户都IP
        String clientIp = request.getRemoteAddr();

        log.info("===============请求信息===============");
        try {
            // 打印请求内容
            log.info("请求地址:" + request.getRequestURL().toString());
            log.info("请求方式:" + request.getMethod());
            log.info("accept:" + request.getHeader("accept"));
//            log.info("origin:" + request.getHeader("Origin"));
            Map m = request.getParameterMap();
            log.info("请求参数 : "+ paramData);
            log.info("请求ip : "+ clientIp);

            //log.info("请求类方法:" + joinPoint.getSignature());
            //log.info("请求类方法参数:" + Arrays.toString(joinPoint.getArgs()));
        } catch (Exception e) {
            log.error("###LogAspectServiceApi.class methodBefore() ### ERROR:", e);
        }
        log.info("=============== end ===============");

        return true;

    }

    /**
     * 后处理回调方法，实现处理器（controller）的后处理，但在渲染视图之前
     * 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) {
        HandlerMethod hm = (HandlerMethod)handler;
//        log.info(" 处理类 {} 方法 {}",hm.getBeanType(),hm.getMethod());
//
//        if(modelAndView != null){
//            //log.info("===============postHandle ===============");
//            log.info("===============返回内容===============");
//            log.info("ModelAndView： "+modelAndView.getViewName());
//            //log.info("===============postHandle end===============");
//        }



    }

    /**
     * 整个请求处理完毕回调方法，即在视图渲染完毕时回调，
     * 如性能监控中我们可以在此记录结束时间并输出消耗时间，
     * 还可以进行一些资源清理，类似于try-catch-finally中的finally，
     * 但仅调用处理器执行链中
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler,
                                Exception ex) {
        log.info("=============== 返回内容 ===============");
        int status = response.getStatus();
        log.info("状态码 {} ",status);
        Object result = request.getAttribute("result");
        if(result!=null){
            log.info("返回值 {} ",result);
        }
        Date start = (Date) request.getAttribute("REQUEST_START_TIME");
        Date end = new Date();
        log.info(" 总耗时 " + (end.getTime() - start.getTime()) + "毫秒；" );
        log.info("=============== end ===============");
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request,
                                               HttpServletResponse response,
                                               Object handler)
            throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }


}
